<template>
  <div class="upload-image">
    <!--
      i 标签 显示上传内的 + 号
      list-type="picture-card" 显示上传的外边框
      action 必传项，作用：图片服务器对应的地址，当你不想使用时，配置为一个 # 号
    -->
    <!-- 核心功能：预览、删除、上传、提示、进度条 -->
    <!--
      :file-list="fileList" 表示上传的图片列表
      :on-preview="handlePictureCardPreview" 预览图片
      :limit="3" 限制上传图片数量
      :class="{disabled: isDisabled}" 当上传的图片超过两张时，添加隐藏类名
      :on-remove="handleRemove" 点击删除时执行的函数
      :http-request:自定义上传，默认覆盖 action
      :on-change="handleChange" 处理文件状态改变时的事件，上传成功和失败都会被调用
      :before-upload：上传文件前的钩子，参数为上传的文件，一般用来校验文件
    -->
    <el-upload
      action="#"
      list-type="picture-card"
      :file-list="fileList"
      :on-preview="handlePictureCardPreview"
      :limit="limit"
      :class="{disabled: isDisabled}"
      :on-remove="handleRemove"
      :http-request="handleRequest"
      :on-change="handleChange"
      :before-upload="beforeUpload"
    >
      <i class="el-icon-plus" />
    </el-upload>
    <el-dialog :visible.sync="dialogVisible" title="预览图片">
      <img width="100%" :src="dialogImageUrl" alt="">
    </el-dialog>
  </div>
</template>

<script>
// api密钥
// SecretId: AKIDPm074qPlvs8AJe0A6oKf8OQHxQffT6WQ
// SecretKey: lJbgV8XjhQuCYknhU7d0EICtPjnbC2jF
import cos from '@/utils/cos'
export default {
  name: 'ImageUpload',

  // 限制传多少张照片
  props: {
    limit: {
      type: Number,
      default: 1
    }
  },

  data() {
    return {
      fileList: [], // [{url: 'xxxx.jpg'}]
      // 显示预览图片
      dialogVisible: false,
      dialogImageUrl: ''
    }
  },

  computed: {
    // 判断上传图片是否超过限定张数
    isDisabled() {
      return this.fileList.length >= this.limit
    },
    // 检测是否正在上传，父组件使用，如果还有在上传的图片，则无法发起请求更改保存
    isAllUpdate() {
      return this.fileList.every(item => item.status === 'success') && this.fileList.length > 0
    }
  },

  methods: {
    // 处理预览头像大图
    handlePictureCardPreview(file) {
      this.dialogImageUrl = file.url
      this.dialogVisible = true
    },

    // 点击删除时执行的函数
    handleRemove(file, fileList) {
      // file 代表删除的图片
      // fileList 表示已删除后的现存的图片列表
      // 而 this.fileList 指的是我们在 data 中声明的数据
      // 写法一：浅拷贝，防止指向相同，不能保证这俩一直同步
      // this.fileList = [...fileList]
      // 写法二：通过上传图片后数组中存的图片的唯一 uid，将 this.fileList 中的数据更新
      this.fileList = this.fileList.filter(item => item.uid !== file.uid)
    },

    // 处理上传
    handleRequest(obj) {
      // console.log(obj)
      // 操作地址详情：https://cloud.tencent.com/document/product/436/64960#.E5.88.9D.E5.A7.8B.E5.8C.96.E5.88.86.E5.9D.97.E4.B8.8A.E4.BC.A0 （点简单对象上传）

      // 找到添加成功的腾讯云返回的图片信息和 data 里面的 this.fileList 中的 uid 相同的那个图片信息对象，在后面返回的腾讯云真实地址替换掉临时地址
      const fileObj = this.fileList.find(item => item.uid === obj.file.uid)
      // 加载效果：loading 效果
      fileObj.status = 'uploading'

      cos.putObject({
        Bucket: 'project-hrsass-1318371026', /* 填入您自己的存储桶，必须字段 */
        Region: 'ap-beijing', /* 存储桶所在地域，例如ap-beijing，必须字段 */
        Key: +new Date() + '_' + obj.file.name, /* 存储在桶里的对象键（例如1.jpg，a/b/test.txt），必须字段，必须唯一，防止重名图片，会发生覆盖，因此加上时间戳*/
        StorageClass: 'STANDARD',
        Body: obj.file, /* 必须，上传文件对象，可以是input[type="file"]标签选择本地文件后得到的file对象 */
        onProgress: function(progressData) {
          // console.log(JSON.stringify(progressData)) // 上传进度
          // 上传进度：loading 效果
          fileObj.percentage = progressData.percent * 100
        }
      }, function(err, data) {
        // console.log(err || data)
        if (err) {
          console.log('上传失败，请稍后重试')
          return
        }
        // 注意：返回 data 里有图片地址，而之前在 data（不是前面那个 data） 的 this.fileList 里展示的是临时地址，需要将其替换
        // 但是：返回的 data 数据里的图片地址，是没有域名的，需要手动加上域名
        fileObj.url = 'https://' + data.Location
        // 小细节：图片上传成功后，会在右上角打个勾
        if (fileObj.percentage === 100) {
          fileObj.status = 'success'
        }
      })
    },

    // 处理文件状态改变时的事件，上传成功和失败都会被调用
    handleChange(file, fileList) {
      // file 代表改变的的图片
      // fileList 表示已改变后的现存的图片列表
      this.fileList.push(file)
    },

    // 处理文件上传前的函数（校验功能）
    beforeUpload(file) {
      // console.log(file)
      // 校验文件类型：
      const imgType = ['image/png', 'image/jpg', 'image/jpeg', 'image/bmp', 'image/gif']
      if (imgType.includes(file.type) === false) {
        this.$message.error('文件上传格式不正确，请重新上传')
        return false
      }
      // 校验文件大小，单位是 B ， 转换为 KB ，在转换为 MB：
      if (file.size / 1024 / 1024 > 2) {
        this.$message.error('图片大小必须小于2MB')
        return false
      }
      return true
    }
  }
}
</script>

<style lang="scss" scoped>
.upload-image{
  width: 500px;
}
.disabled {
  ::v-deep {
    .el-upload {
      display: none;
    }
  }
}
</style>
